#ifndef _FLASHUSER_H
#define _FLASHUSER_H

#include <stdint.h>
#include "stm32g4xx.h"
#include "bsp_flash.h"
#include "module_config.h"

#ifdef __cplusplus
 extern "C" {
#endif

#define BOOTLOADER_SIZE                           0x8000      //32k
#define USER_INFO_SIZE                            0X8000      //32K
#define APP_MAX_SIZE                              0x70000     //448k
#define CMBACKTRACE_SIZE                          BSP_FLASH_PAGE_SIZE

#define STM32_FLASH_BASE                          0x08000000 	//flash start address
#define BOOTLOADER_START_ADDR                     STM32_FLASH_BASE                                  //0X08000000 ~ 0x8007FFF   Size: 32k
#define USER_INFO_START_ADDR                      (BOOTLOADER_START_ADDR+BOOTLOADER_SIZE)           //0x08008000 ~ 0x800FFFF   Size: 32k

#define APP_TEMP_A_START_ADDR                     (USER_INFO_START_ADDR+USER_INFO_SIZE)             //0x08010000 ~ 0x807FFFF   Size: 448k
#define APP_TEMP_B_START_ADDR                     (APP_TEMP_A_START_ADDR+APP_MAX_SIZE)              //0x08080000 ~ 0x80EFFFF   Size: 448k
#define CMBACKTRACE_START_ADDR                    (APP_TEMP_B_START_ADDR+APP_MAX_SIZE)              //0x080F0000 ~ 0x80FFFFF   Size: 64k

#define OTA_DATA_MAX_SIZE                         BSP_FLASH_PAGE_SIZE
#define CONFIG_DATA_MAX_SIZE                      BSP_FLASH_PAGE_SIZE
#define MODULE_DATA_MAX_SIZE                      BSP_FLASH_PAGE_SIZE
#define BACK_UP_DATA_MAX_SIZE                     BSP_FLASH_PAGE_SIZE
#define FACTORY_DATA_MAX_SIZE                     BSP_FLASH_PAGE_SIZE
#define BMS_DATA_MAX_SIZE                         BSP_FLASH_PAGE_SIZE


#define OTA_INFO_PAGE_START_ADDR                  (USER_INFO_START_ADDR)                                    //0x08008000     
#define CONFIG_INFO_PAGE_START_ADDR               (OTA_INFO_PAGE_START_ADDR+OTA_DATA_MAX_SIZE)              //0x08009000         
#define MODULE_DATA_START_ADDR                    (CONFIG_INFO_PAGE_START_ADDR+CONFIG_DATA_MAX_SIZE)        //0x0800A000     
#define INFO_BACKUP_START_ADDR                    (MODULE_DATA_START_ADDR+MODULE_DATA_MAX_SIZE)            //0x0800B000                  
#define FACTORY_INFO_PAGE_START_ADDR              (INFO_BACKUP_START_ADDR+BACK_UP_DATA_MAX_SIZE)            //0x0800C000 
#define BMS_DATA_PAGE_START_ADDR                  (FACTORY_INFO_PAGE_START_ADDR+FACTORY_DATA_MAX_SIZE)      //0x0800D000                  //0x0800E000

#define OTA_DATA_FLAG       0
#define FACTOR_DATA_FLAG    1
#define USER_INFO_DATA_FALG 2
#define CFG_DATA_FLAG       3

#define PN_LEN          16
#define IAPKEY_LEN      16
#define RANDOM_DATA_LEN 6
#define BMS_PN_LEN      16
#define SUBG_SN_LEN     16


#define DATA_HEADER_LENGTH 8
#define OLD_DATA_CONFIG_HEADER         0xA22A
#define DATA_CONFIG_HEADER             0xA22B

#define OLD_DATA_NESSARY_HEADER        0xA22A
#define DATA_NESSARY_HEADER            0xA55A

#define DATA_MODULE_HEADER             0xA33A

/*  firmware update status  */
typedef struct{
    uint8_t dataflag;
    uint8_t download_flag;
    uint8_t update_flag;
    uint32_t firmware_size;
    uint32_t check_sum;
}firmwareUpdateStatusTypeDef;

typedef struct{ 
    uint16_t header;
    uint16_t datalen;
    uint16_t crc16_header; // header + datalen
    uint16_t crc16_data;
    uint8_t data[BSP_FLASH_PAGE_SIZE - DATA_HEADER_LENGTH];
}flashdataTypeDef;

typedef struct{
    uint8_t bmsPN[ECU_PN_MAX+1];
#if defined (MODULE_INCLUDE_SUBG)
    uint32_t subg_band; // not need map old subg,now not have 868 machine,lixiang and shangdong confirm together;
    uint8_t subgsn[FLASH_SUBG_SN_MAX+1];
    uint8_t subg_next_pair_id;
#endif
}dataConfigTypeDef;

/* module config parameter */
enum
{
    MODULE_INDEX_RGB_LIGHT = 0,
    MODULE_INDEX_BUMPER,
    MODULE_INDEX_RAIN,
    MODULE_INDEX_SUBG,

    MODULE_INDEX_MAX,
};

// rgb light module type
enum
{
    MODULE_RGB_LIGHT_NULL = 0,
    MODULE_RGB_LIGHT_LITTLE_CIRCLE,


    MODULE_RGB_LIGHT_MAX,
};

// bumper module type
enum
{
    MODULE_BUMPER_NULL = 0,
    MODULE_BUMPER_SWITCH,
    
    MODULE_BUMPER_MAX,
};

// rgb light module type
enum
{
    MODULE_RAIN_NULL = 0,
    MODULE_RAIN_CAPACITANCE,

    MODULE_RAIN_MAX,
};

enum
{
    MODULE_SUBG_NULL = 0,
    MODULE_SUBG_4463,

    MODULE_SUBG_MAX,
};

typedef struct{
    uint8_t rgb_light;
    uint8_t bumper;
    uint8_t rain;
    uint8_t subg;
}ModuleConfig_st;

/* module config parameter end*/

typedef enum
{
    DATA_ID_FAC_PN = 0,
    DATA_ID_FAC_RANDOM,
    DATA_ID_FAC_KEY,

    DATA_ID_FAC_MAX,

    DATA_ID_CONFIG_BASE = 40,
    DATA_ID_CONFIG_SUBG_BAND = DATA_ID_CONFIG_BASE,
    DATA_ID_CONFIG_SUBG_BMS_PN,
    DATA_ID_CONFIG_SUBG_NEXT_PAIR_ID,
    DATA_ID_CONFIG_PAIR_BASE_INFO,
    DATA_ID_CONFIG_PAIR_SLAVE_INFO,

    DATA_ID_CONFIG_MAX,
}en_DataIdIndex;


typedef enum
{
    FLASH_NORMAL = 0,
    FLASH_HEADER_CRC_FAILED,
    FLASH_DATA_CRC_FAILED,
    FLASH_WRITE_FAILED,
    FLASH_INVAILD_PARAM,
    FLASH_EMPTY,
    FLASH_ERASE_FAILED,
    FLASH_READ_FAILED,
    FLASH_CHECK_FAILED,
    FLASH_INVALID_ADDR,
}en_FlashOperation;


#define flash_erase        bsp_flash_erase
#define flash_write        bsp_flash_write
#define flash_read         bsp_flash_read

int8_t flash_program_write(uint32_t addr,uint8_t* writebuff,uint32_t len);
int8_t flash_program_erase(uint32_t addr,uint32_t len);
int8_t backup_info_recover(void);
int8_t write_ota_data(firmwareUpdateStatusTypeDef* data);
int8_t read_ota_data(firmwareUpdateStatusTypeDef* data);
int8_t write_cfg_data(dataConfigTypeDef* data);
int8_t read_cfg_data(dataConfigTypeDef* data);
int8_t write_factory_data(FactoryDataNessary_st* data);
int8_t read_factory_data(FactoryDataNessary_st* data);
int8_t write_module_data(ModuleConfig_st* data);
int8_t read_module_data(ModuleConfig_st* data);

#ifdef __cplusplus
}
#endif

#endif

